/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package model;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

/**
 *
 * @author Eleftherios
 */
@Entity
@Table(name = "MUSIC_GROUP")
@XmlRootElement
@NamedQueries({
    @NamedQuery(name = "MusicGroup.findAll", query = "SELECT m FROM MusicGroup m"),
    @NamedQuery(name = "MusicGroup.findByMusicGroupId", query = "SELECT m FROM MusicGroup m WHERE m.musicGroupId = :musicGroupId"),
    @NamedQuery(name = "MusicGroup.findByName", query = "SELECT m FROM MusicGroup m WHERE m.name = :name"),
    @NamedQuery(name = "MusicGroup.findByFormationDate", query = "SELECT m FROM MusicGroup m WHERE m.formationDate = :formationDate")})
public class MusicGroup implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "MUSIC_GROUP_ID")
    private Integer musicGroupId;
    @Basic(optional = false)
    @Column(name = "NAME")
    private String name;
    @Basic(optional = false)
    @Column(name = "FORMATION_DATE")
    @Temporal(TemporalType.DATE)
    private Date formationDate;
    @JoinTable(name = "GROUP_OWNER", joinColumns = {
        @JoinColumn(name = "MUSIC_GROUP", referencedColumnName = "MUSIC_GROUP_ID")}, inverseJoinColumns = {
        @JoinColumn(name = "ALBUM", referencedColumnName = "ALBUM_ID")})
    @ManyToMany
    private List<Album> albumList;
    
    @JoinTable(name = "HAS_MEMBERS", joinColumns = {
        @JoinColumn(name = "MUSIC_GROUP", referencedColumnName = "MUSIC_GROUP_ID")}, inverseJoinColumns = {
        @JoinColumn(name = "ARTIST", referencedColumnName = "ARTIST_ID")})
    @ManyToMany
    private List<Artist> artistList;

    public MusicGroup() {
    }

    public MusicGroup(Integer musicGroupId) {
        this.musicGroupId = musicGroupId;
    }

    public MusicGroup(Integer musicGroupId, String name, Date formationDate) {
        this.musicGroupId = musicGroupId;
        this.name = name;
        this.formationDate = formationDate;
    }

    public Integer getMusicGroupId() {
        return musicGroupId;
    }

    public void setMusicGroupId(Integer musicGroupId) {
        this.musicGroupId = musicGroupId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getFormationDate() {
        return formationDate;
    }

    public void setFormationDate(Date formationDate) {
        this.formationDate = formationDate;
    }

        
    public List<MusicGroup> read(Boolean All)   {
       String Sql="Select * From Music_Group Order By Name";
       if(All==false){
           Sql = "Select * From Music_Group Where Music_Group_Id = " + this.musicGroupId.toString();
       } 
       dataLayer DataLayer = new dataLayer();
       ResultSet res = DataLayer.ExecuteQuery(Sql);
       List<MusicGroup> list = new ArrayList<>();
       try
            {
                     this.name="";
                     this.formationDate=null;
                 while (res.next()) {
                     MusicGroup row = new MusicGroup();
                                          
                     this.musicGroupId=res.getInt("Music_Group_Id");
                     this.name=res.getString("Name");
                     this.formationDate=res.getDate("Formation_Date");
                                                          
                     row.setMusicGroupId(musicGroupId);
                     row.setName(name);
                     row.setFormationDate(formationDate);                     
                     list.add(row);                     
                  }
            }
             catch ( SQLException err ) {
                System.out.println( err.getMessage( ) );
             }  
       return list;
    }
    
    
     public long update(){
       String MyDate = Integer.toString(formationDate.getMonth()+1) + "/" + Integer.toString(formationDate.getDate()) + "/" + Integer.toString(formationDate.getYear()+1900);
       String Sql = "Update Music_Group Set Name = '" + name + "'" +
                                     ", formation_Date = '" + MyDate + "'" + 
                     " Where Music_Group_Id = " + musicGroupId.toString();
       dataLayer DataLayer = new dataLayer();
       return DataLayer.ExecuteUpdate(Sql);
    }
    
    public long insert(){
        String MyDate = Integer.toString(formationDate.getMonth()+1) + "/" + Integer.toString(formationDate.getDate()) + "/" + Integer.toString(formationDate.getYear()+1900);
        String Sql = "Insert Into Music_Group (Name , " +
                                     "formation_Date) Values ('" +
                                     name + 
                                     "','" + MyDate + "'" + ")";
       dataLayer DataLayer = new dataLayer();
       return DataLayer.ExecuteUpdate(Sql);
    }
    
    public long delete(){
       String Sql = "Delete From  Music_Group Where Music_Group_Id = " + musicGroupId.toString();
       dataLayer DataLayer = new dataLayer();
       return DataLayer.ExecuteUpdate(Sql);
    }
          
    @XmlTransient
    public List<Album> getAlbumList() {
        
        return albumList;
    }

    public void setAlbumList(List<Album> albumList) {
        
        
        this.albumList = albumList;
    }

    @XmlTransient
    public List<Artist> getArtistList(boolean outOfGroup) 
            // outOfGroup = true τότε φέρε τους artists εκτός group
            // outOfGroup = false τότε φέρε τους artists του group
    {
        String eq = "=" ;
        if(outOfGroup==true) { eq = " IS NULL OR HAS_MEMBERS.MUSIC_GROUP <> "; }
        
        String SQL = "SELECT ARTIST.* FROM (HAS_MEMBERS LEFT JOIN MUSIC_GROUP ON HAS_MEMBERS.MUSIC_GROUP = MUSIC_GROUP.MUSIC_GROUP_ID) RIGHT JOIN ARTIST ON HAS_MEMBERS.ARTIST = ARTIST.ARTIST_ID" +
                          " WHERE HAS_MEMBERS.MUSIC_GROUP " + eq + 
                          " " + musicGroupId.toString() ;
        Artist MyClass = new Artist();
        return MyClass.read(Boolean.TRUE, SQL);
    }
    
//    public void setArtistList(List<Artist> artistList) {
//        this.artistList = artistList;
//    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (musicGroupId != null ? musicGroupId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof MusicGroup)) {
            return false;
        }
        MusicGroup other = (MusicGroup) object;
        if ((this.musicGroupId == null && other.musicGroupId != null) || (this.musicGroupId != null && !this.musicGroupId.equals(other.musicGroupId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "model.MusicGroup[ musicGroupId=" + musicGroupId + " ]";
    }
    
}
